<template>
  <div id="container">
  </div>
</template>

<script>

// 引入antv-G6
import G6 from '@antv/g6'
// 树图的数据
import { treedata } from '@/common/treedata'

// x是中心x的坐标 y 是中心的y坐标 r是半径
// M-移至  A-椭圆弧 Z-关闭路径 L-线到的位置
// 折叠图标
const COLLAPSE_ICON = function COLLAPSE_ICON (x, y, r) {
// 正三角
  return [['M', x, y], ['L', x + r, y - r], ['L', x + r * 2, y], ['Z']]
}
// 展开图标
// const EXPAND_ICON = function EXPAND_ICON (x, y, r) {
//   // 倒三角
//   return [['M', x, y], ['L', x + r, y + r], ['L', x + r * 2, y], ['Z']]
// }
G6.registerNode(
  'icon-node',
  {
    options: {
      size: [60, 20], // 宽高
      stroke: '#91d5ff', // 变颜色
      fill: '#fff'// 填充色
    },
    // draw是绘制后的附加操作-节点的配置项  图形分组，节点中图形对象的容器
    draw (cfg, group) {
      // 获取节点的配置
      const styles = this.getShapeStyle(cfg)
      //   console.log(cfg)
      // 解构赋值
      const { labelCfg = {} } = cfg

      const w = styles.width
      const h = styles.height
      //   console.log(cfg.children)// undefined

      // 向分组中添加新的图形 图形 配置 rect矩形 xy 代表左上角坐标 w h是宽高
      const keyShape = group.addShape('rect', {
        attrs: {
          ...styles,
          x: -w / 2,
          y: -h / 2
        }
      })
      // 如果有子级就添加折叠图标
      if (cfg.children !== undefined) {
        //   添加折叠图标
        group.addShape('marker', {
          attrs: {
            x: 55 - w / 2,
            y: 47 - h / 2,
            r: 6,
            stroke: '#73d13d',
            fill: '#73d13d',
            cursor: 'pointer',
            symbol: COLLAPSE_ICON
          },
          name: 'collapse-item'
        })
      }
      //   添加折叠图标
      //   group.addShape('marker', {
      //     attrs: {
      //       x: 55 - w / 2,
      //       y: 47 - h / 2,
      //       r: 6,
      //       stroke: '#73d13d',
      //       fill: '#73d13d',
      //       cursor: 'pointer',
      //       symbol: COLLAPSE_ICON
      //     },
      //     name: 'collapse-item'
      //   })
      //   添加展开图标
      // group.addShape('marker', {
      //   attrs: {
      //     x: 55 - w / 2,
      //     y: 41 - h / 2,
      //     r: 6,
      //     stroke: '#73d13a',
      //     fill: '#73d13a',
      //     cursor: 'pointer',
      //     symbol: EXPAND_ICON
      //   },
      //   name: 'expand-item'
      // })

      // 文本文字的配置
      if (cfg.label) {
        group.addShape('text', {
          attrs: {
            ...labelCfg.style,
            text: cfg.label,
            x: 0 - w / 2,
            y: 25 - h / 2
            // position: 'center'
          }
        })
      }

      return keyShape
    },
    // 更新节点后的操作，一般同 afterDraw 配合使用
    update: undefined
  },
  'rect'
)
G6.registerEdge('flow-line', {
  // 绘制后的附加操作
  draw (cfg, group) {
    // 边两端与起始节点和结束节点的交点；
    const startPoint = cfg.startPoint
    const endPoint = cfg.endPoint
    // 边的配置
    const { style } = cfg
    const shape = group.addShape('path', {
      attrs: {
        stroke: style.stroke, // 边框的样式
        endArrow: style.endArrow, // 结束箭头
        // 路径
        path: [
          ['M', startPoint.x, startPoint.y],
          ['L', startPoint.x, (startPoint.y + endPoint.y) / 2],
          ['L', endPoint.x, (startPoint.y + endPoint.y) / 2],
          ['L', endPoint.x, endPoint.y]
        ]
      }
    })

    return shape
  }
})
// 默认的鼠标悬停会加粗,边框颜色改变
const defaultStateStyles = {
  hover: {
    stroke: '#1890ff',
    lineWidth: 2
  }
}

// 默认节点的颜色 边 圆角的配置
const defaultNodeStyle = {
  fill: '#fff',
  stroke: '#ccc',
  radius: 5
}

// 默认边的颜色 末尾箭头
const defaultEdgeStyle = {
  stroke: '#ccc'
//   endArrow: {
//     path: 'M 0,0 L 12, 6 L 9,0 L 12, -6 Z',
//     // fill: 'black',
//     d: -20
//   }
}

// 默认布局
// compactBox 紧凑树布局
// 从根节点开始，同一深度的节点在同一层，并且布局时会将节点大小考虑进去。
const defaultLayout = {
  type: 'compactBox', // 布局类型树
  direction: 'TB', // TB 根节点在上，往下布局
  getId: function getId (d) { // 节点 id 的回调函数
    return d.id
  },
  getHeight: function getHeight () { // 节点高度的回调函数
    return 16
  },
  getWidth: function getWidth () { // 节点宽度的回调函数
    return 16
  },
  getVGap: function getVGap () { // 节点纵向间距的回调函数
    return 40
  },
  getHGap: function getHGap () { // 节点横向间距的回调函数
    return 70
  }
}

// 文本配置项
const defaultLabelCfg = {
  style: {
    fill: '#000',
    fontSize: 15
  }
}

export default {
  name: 'Home',

  data () {
    return {
      // 树形图的数据
    //   treedata: treedata
    }
  },
  methods: {
    // 树图初始化
    G6init () {
      if (typeof window !== 'undefined') {
        window.onresize = () => {
          if (!graph || graph.get('destroyed')) return
          if (!container || !container.scrollWidth || !container.scrollHeight) return
          graph.changeSize(container.scrollWidth, container.scrollHeight)
        }
      }
      // 获取容器
      const container = document.getElementById('container')
      // 获取容器的宽高
      const width = container.scrollWidth
      const height = container.scrollHeight || 500

      const menu = new G6.Menu({
        offsetX: 10,
        offsetY: 10,
        itemTypes: ['node'],
        // 右击弹窗框
        getContent (e) {
          const outDiv = document.createElement('div')
          outDiv.style = 'width:100px;height:65px;font-size:14px;padding:4px 0;'
          outDiv.innerHTML = `<ul>
           <li>增加节点</li>
           <li>删除节点</li>
           <li>查看节点</li>
           <li>编辑节点</li>
           </ul>`
          return outDiv
        },
        // target 当前点击的dom item
        handleMenuClick (target, item) {
        //   // 获取当前
        //   const model = item._cfg
        //   //   console.log(target.innerText)
        //   model.children = Array.from(model.children)
          const model = item.getModel()
          // 添加子节点
          if (target.innerText === '增加节点') {
            const id = `${model.id}-${Math.random()}`
            if (!model.children) {
              model.children = []
            }
            model.children.push({
              id,
              label: id.substr(0, 8)

            })

            graph.updateChild(model, model.id)
          }
        }

      })

      // Graph 是 G6 图表的载体-实例化
      const graph = new G6.TreeGraph({
        container: 'container', // 图的 DOM 容器
        width,
        height,
        linkCenter: true, // 指定边是否连入节点的中心
        plugins: [menu], // 插件  minimap
        modes: { // 交互模式

          default: [
            {
            // 这个是可以展开可以收起
              type: 'collapse-expand',
              onChange: function onChange (item, collapsed) {
                const data = item.get('model')
                data.collapsed = collapsed
                console.log(item)
                return true
              }
            },
            'drag-canvas',
            'zoom-canvas'
          ]
        },
        // 默认状态下节点的配置
        defaultNode: {
          type: 'icon-node',
          size: [120, 40],
          style: defaultNodeStyle,
          labelCfg: defaultLabelCfg
        },
        // 默认状态下边的配置，
        defaultEdge: {
          type: 'flow-line',
          style: defaultEdgeStyle
        },
        // 各个状态下节点的样式-，例如 hover、selected，3.1 版本新增。
        nodeStateStyles: defaultStateStyles,

        // 各个状态下边的样式-，例如 hover、selected，3.1 版本新增。
        edgeStateStyles: defaultStateStyles,
        // 布局配置项
        layout: defaultLayout
      })

      graph.data(treedata)

      // 根据提供的数据渲染视图。
      graph.render()
      // 让画布内容适应视口。
      graph.fitView()
      // 改变视口的缩放比例，在当前画布比例下缩放，是相对比例。
      //   graph.zoom(1)
      graph.on('node:click', (evt) => {
        // const { item, target } = evt
        // const targetType = target.get('type')
        // const name = target.get('name')
        // console.log(targetType)// marker rect
        // console.log(name)// expand-item  collapse-item undefined
        // console.log(item._cfg.children.length)// node 0 3
        // if (item._cfg.children.length) {
        //   group.addShape('marker', {
        //     attrs: {
        //       x: 55 - w / 2,
        //       y: 41 - h / 2,
        //       r: 6,
        //       stroke: '#73d13a',
        //       fill: '#73d13a',
        //       cursor: 'pointer',
        //       symbol: EXPAND_ICON
        //     },
        //     name: 'expand-item'
        //   })
        // }
      })
    }
  },
  mounted () {
    this.G6init()
  }
}
</script>
<style scoped>
#container{
    height: 70%;
    width: 70%;
}
</style>
